package com.bucks;

import com.bucks.bean.Coffee;
import com.bucks.bean.CoffeeOrder;
import com.bucks.bean.OrderState;
import com.bucks.repository.CoffeeOrderRepository;
import com.bucks.repository.CoffeeRepository;
import lombok.extern.slf4j.Slf4j;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.transaction.Transactional;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**

 * @date 2019-10-17
 */
@SpringBootApplication
@EnableJpaRepositories
@EnableTransactionManagement
@Slf4j
public class SpringBucksSpringJpaApplication implements ApplicationRunner {

    @Autowired
    private CoffeeRepository coffeeRepository;

    @Autowired
    private CoffeeOrderRepository coffeeOrderRepository;

    public static void main(String[] args) {
        SpringApplication.run(SpringBucksSpringJpaApplication.class, args);
    }

    @Override
    @Transactional(rollbackOn = SQLException.class)
    public void run(ApplicationArguments args){
        initOrders();
        findOrders();
    }



    public void initOrders() {
        log.info("====================initOrders======================");
        Coffee espresso = Coffee.builder().name("espresso")
                .price(Money.of(CurrencyUnit.of("CNY"),20.0)).build();
        coffeeRepository.save(espresso);
//        log.info("Coffee : "+espresso);

        Coffee latte = Coffee.builder().name("latte")
                .price(Money.of(CurrencyUnit.of("CNY"),35.0)).build();
        coffeeRepository.save(latte);
//        log.info("Coffee : "+latte);

        Coffee meishi = Coffee.builder().name("meishi")
                .price(Money.of(CurrencyUnit.of("CNY"),33.0)).build();
        coffeeRepository.save(latte);
//        log.info("Coffee : "+latte);

        CoffeeOrder newOrder = CoffeeOrder.builder().customer("customer")
                .items(Collections.singletonList(espresso))
                .state(OrderState.INIT)
                .build();
        coffeeOrderRepository.save(newOrder);
//        log.info("Order :"+newOrder);
    }

    public void findOrders() {
        log.info("====================findOrders======================");
        coffeeRepository.findAll(Sort.by(Sort.DEFAULT_DIRECTION,"id"))
                .forEach(coffee -> log.info("Loading {}",coffee));

        List<CoffeeOrder> list = coffeeOrderRepository.findTop3ByOrderByUpdateTimeDescIdAsc();
        log.info("====================Result===================");
        log.info("findTop3ByOrderByUpdateTimeDescIdAsc :"+getJoinedOrderId(list));

        list = coffeeOrderRepository.findByCustomerOrderById("customer");
        log.info("====================Result===================");
        log.info("findByCustomerOrderById :"+getJoinedOrderId(list));

        // 不开启事务会因为没Session而报LazyInitializationException
        list.forEach(coffeeOrder -> {
            log.info("Order {}", coffeeOrder.getId());
            coffeeOrder.getItems().forEach(i -> log.info(" Item {} ",i));
        });

        list = coffeeOrderRepository.findByItems_Name("latte");
        log.info("findByItems_Name :",getJoinedOrderId(list));
    }

    private String getJoinedOrderId(List<CoffeeOrder> list){
        return list.stream().map(coffeeOrder -> coffeeOrder.getId().toString())
                .collect(Collectors.joining(","));
    }
}
